Completed
Pull Request — develop (#92)
by
unknown
13:53
created

main.js ➔ define   B

Complexity

Conditions 1
Paths 4

Size

Total Lines 284

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
c 2
b 0
f 1
nc 4
nop 5
dl 0
loc 284
rs 8.2857

12 Functions

Rating   Name   Duplication   Size   Complexity  
A main.js ➔ ... ➔ bindDomEvents 0 14 1
A main.js ➔ ... ➔ bindCustomEvents 0 18 1
B main.js ➔ ... ➔ initializeList 0 36 1
A main.js ➔ ... ➔ updateList 0 5 1
A main.js ➔ ... ➔ .getItemContent 0 3 1
B main.js ➔ ... ➔ typeChange 0 15 5
A main.js ➔ ... ➔ .removeHandler 0 11 3
A main.js ➔ ... ➔ .sortHandler 0 3 1
B main.js ➔ ... ➔ getAddOverlayData 0 26 2
B main.js ➔ ... ➔ startOverlay 0 60 4
A main.js ➔ ... ➔ .initialize 0 12 1
A main.js ➔ ... ➔ .getUrl 0 10 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/*
2
 * This file is part of Sulu.
3
 *
4
 * (c) MASSIVE ART WebServices GmbH
5
 *
6
 * This source file is subject to the MIT license that is bundled
7
 * with this source code in the file LICENSE.
8
 */
9
10
/**
11
 * Article-Selection content type.
12
 *
13
 * Allows selection of multiple articles.
14
 */
15
define([
16
    'underscore',
17
    'config',
18
    'text!./overlay.html',
19
    'text!./contentItem.html',
20
    'text!/admin/api/articles/fields'
21
], function(_, Config, overlayTemplate, contentItemTemplate, fieldsResponse) {
22
23
    'use strict';
24
25
    var fields = JSON.parse(fieldsResponse),
26
27
        config = Config.get('sulu_article'),
28
29
        defaults = {
30
            options: {
31
                url: '/admin/api/articles',
32
                eventNamespace: 'sulu.article-selection',
33
                resultKey: 'articles',
34
                dataAttribute: 'article-selection',
35
                dataDefault: [],
36
                hidePositionElement: true,
37
                hideConfigButton: true,
38
                navigateEvent: 'sulu.router.navigate',
39
                translations: {
40
                    noContentSelected: 'sulu_article.selection.no-result'
41
                }
42
            },
43
44
            templates: {
45
                overlay: overlayTemplate,
46
                contentItem: contentItemTemplate
47
            },
48
49
            translations: {
50
                title: 'public.title',
51
                overlayTitle: 'sulu_article.title'
52
            }
53
        },
54
55
        /**
56
         * Handles aura-events.
57
         */
58
        bindCustomEvents = function() {
59
            this.sandbox.on(
60
                'husky.overlay.article-selection.' + this.options.instanceName + '.add.initialized',
61
                initializeList.bind(this)
62
            );
63
64
            this.sandbox.on(
65
                'husky.overlay.article-selection.' + this.options.instanceName + '.add.opened',
66
                updateList.bind(this)
67
            );
68
69
            // adjust position of overlay after column-navigation has initialized
70
            this.sandbox.on('husky.datagrid.article.view.rendered', function() {
71
                this.sandbox.emit('husky.overlay.article-selection.' + this.options.instanceName + '.add.set-position');
72
            }.bind(this));
73
74
            this.sandbox.on('husky.tabs.overlayarticle-selection.' + this.options.instanceName + '.add.item.select', typeChange.bind(this));
75
        },
76
77
        /**
78
         * Initializes list in the overlay
79
         */
80
        initializeList = function() {
81
            this.sandbox.start([
82
                {
83
                    name: 'search@husky',
84
                    options: {
85
                        appearance: 'white small',
86
                        instanceName: this.options.instanceName + '-article-search',
87
                        el: '#article-selection-' + this.options.instanceName + '-search'
88
                    }
89
                },
90
                {
91
                    name: 'datagrid@husky',
92
                    options: {
93
                        el: '#article-selection-' + this.options.instanceName + '-list',
94
                        instanceName: this.options.instanceName,
95
                        url: this.url,
96
                        preselected: this.getData() || [],
97
                        resultKey: this.options.resultKey,
98
                        sortable: false,
99
                        columnOptionsInstanceName: '',
100
                        clickCallback: function(item) {
101
                            this.sandbox.emit('husky.datagrid.' + this.options.instanceName + '.toggle.item', item);
102
                        }.bind(this),
103
                        selectedCounter: true,
104
                        searchInstanceName: this.options.instanceName + '-article-search',
105
                        searchFields: ['id', 'title'],
106
                        paginationOptions: {
107
                            dropdown: {
108
                                limit: 20
109
                            }
110
                        },
111
                        matchings: fields
112
                    }
113
                }
114
            ]);
115
        },
116
117
        /**
118
         * Updates the datagrid when opening the overlay again
119
         */
120
        updateList = function() {
121
            var data = this.getData() || [];
122
123
            this.sandbox.emit('husky.datagrid.' + this.options.instanceName + '.selected.update', data);
124
        },
125
126
        /**
127
         * Handle dom events
128
         */
129
        bindDomEvents = function() {
130
            this.sandbox.dom.on(this.$el, 'click', function() {
131
                return false;
132
            }.bind(this), '.search-icon');
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
133
134
            this.sandbox.dom.on(this.$el, 'keydown', function(e) {
135
                if (event.keyCode === 13) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if event.keyCode === 13 is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
Bug introduced by
The variable event seems to be never declared. If this is a global, consider adding a /** global: event */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
136
                    e.preventDefault();
137
                    e.stopPropagation();
138
139
                    return false;
140
                }
141
            }.bind(this), '.search-input');
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
142
        },
143
144
        /**
145
         * Starts the overlay component
146
         */
147
        startOverlay = function() {
148
            var $element = this.sandbox.dom.createElement('<div/>'),
149
                $data = $(this.templates.overlay({instanceName: this.options.instanceName})),
150
                types = config.types,
151
                typeNames = config.typeNames,
152
                tabs = false;
153
            this.sandbox.dom.append(this.$el, $element);
154
155
            // load all for default
156
            this.url = this.options.url + '?locale=' + this.options.locale;
157
158
            if (1 !== typeNames.length) {
159
                tabs = [];
160
                if (config.displayTabAll === true) {
161
                    tabs.push(
162
                        {
163
                            title: 'public.all',
164
                            key: null,
165
                            data: $data
166
                        }
167
                    );
168
                } else {
169
                    // if not all tab is first load only for the first type
170
                    var delimiter = (this.options.url.indexOf('?') === -1) ? '?' : '&';
171
172
                    this.url = this.options.url + delimiter + 'locale=' + this.options.locale + '&type=' + typeNames[0];
173
                }
174
175
                // add tab item for each type
176
                _.each(typeNames, function(type) {
177
                    tabs.push(
178
                        {
179
                            title: types[type].title,
180
                            data: $data
181
                        }
182
                    );
183
                }.bind(this));
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
184
185
                $data = null;
186
            }
187
188
            this.sandbox.start([
189
                {
190
                    name: 'overlay@husky',
191
                    options: {
192
                        triggerEl: this.$addButton,
193
                        cssClass: 'article-content-overlay',
194
                        el: $element,
195
                        removeOnClose: false,
196
                        container: this.$el,
197
                        instanceName: 'article-selection.' + this.options.instanceName + '.add',
198
                        skin: 'large',
199
                        okCallback: getAddOverlayData.bind(this),
200
                        title: this.translations.overlayTitle,
201
                        tabs: tabs,
202
                        data: $data
203
                    }
204
                }
205
            ]);
206
        },
207
208
        /**
209
         * Retrieve data from datagrid and keep sorting of ids.
210
         */
211
        getAddOverlayData = function() {
212
            var data = [],
213
                oldData = this.getData();
214
215
            this.sandbox.emit('husky.datagrid.' + this.options.instanceName + '.items.get-selected', function(selected) {
216
                this.sandbox.util.foreach(selected, function(item) {
217
                    var index = oldData.indexOf(item);
218
219
                    if (index !== -1) {
220
                        data[index] = item;
221
                    } else {
222
                        data.push(item);
223
                    }
224
                }.bind(this));
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
225
            }.bind(this));
226
227
            var keys = Object.keys(data),
228
                result = [],
229
                i, len = keys.length;
230
231
            for (i = 0; i < len; i++) {
232
                result.push(data[keys[i]]);
233
            }
234
235
            this.setData(result);
236
        },
237
238
        typeChange = function(item) {
239
            this.type = null;
240
241
            if (item.name) {
242
                for (var type in config.types) {
243
                    if (config.types.hasOwnProperty(type) && config.types[type].title === item.name) {
244
                        this.type = type;
245
246
                        break;
247
                    }
248
                }
249
            }
250
251
            this.sandbox.emit('husky.datagrid.' + this.options.instanceName + '.url.update', {type: this.type});
252
        };
253
254
    return {
255
256
        defaults: defaults,
257
258
        type: 'itembox',
259
260
        initialize: function() {
261
            // sandbox event handling
262
            bindCustomEvents.call(this);
263
264
            this.render();
265
266
            // init overlays
267
            startOverlay.call(this);
268
269
            // handle dom events
270
            bindDomEvents.call(this);
271
        },
272
273
        getUrl: function(data) {
274
            var delimiter = (this.options.url.indexOf('?') === -1) ? '?' : '&';
275
276
            return [
277
                this.options.url,
278
                delimiter,
279
                'locale=' + this.options.locale,
280
                '&', this.options.idsParameter, '=', (data || []).join(',')
281
            ].join('');
282
        },
283
284
        getItemContent: function(item) {
285
            return this.templates.contentItem({item: item, locale: this.options.locale});
286
        },
287
288
        sortHandler: function(ids) {
289
            this.setData(ids, false);
290
        },
291
292
        removeHandler: function(id) {
293
            var data = this.getData();
294
            for (var i = -1, length = data.length; ++i < length;) {
295
                if (id === data[i]) {
296
                    data.splice(i, 1);
297
                    break;
298
                }
299
            }
300
301
            this.setData(data, false);
302
        }
303
    };
304
});
305